/**************************************************************************
**
** created by winter, 20181023
**
**************************************************************************/

#ifndef PACKAGEMANAGEROBJ_H
#define PACKAGEMANAGEROBJ_H

#include "packagemanagercore.h"
#include "igui.h"

#include <QtCore/QEvent>
#include <QtCore/QMetaType>
#include <QtCore/QTimer>

#include <QWizard>
#include <QWizardPage>
#include <QSpacerItem>
#include <QMessageBox>

// FIXME: move to private classes
QT_BEGIN_NAMESPACE
class QAbstractButton;
class QCheckBox;
class QLabel;
class QLineEdit;
class QListWidget;
class QListWidgetItem;
class QProgressBar;
class QRadioButton;
class QTextBrowser;
class QWinTaskbarButton;
QT_END_NAMESPACE

namespace QInstaller {

class PackageManagerPageObj;
class PackageManagerCore;
class PackageManagerPage;
class PerformInstallationForm;


// -- PackageManagerObj

class INSTALLER_EXPORT PackageManagerObj : public QObject,public igui
{
    Q_OBJECT

public:
    explicit PackageManagerObj(PackageManagerCore *core, QObject *parent = 0);
    virtual ~PackageManagerObj() = 0;

    void loadControlScript(const QString& scriptPath);
    void callControlScriptMethod(const QString& methodName);

    //QWidget *pageById(int id) const;
    //QWidget *pageByObjectName(const QString &name) const;

    //QWidget *currentPageWidget() const;
    //QWidget *pageWidgetByObjectName(const QString &name) const;

    //QString defaultButtonText(int wizardButton) const;
    //void clickButton(int wizardButton, int delayInMs = 0);
    //bool isButtonEnabled(int wizardButton);

    //void useSettingsButton(bool use);
    //void showSettingsButton(bool show);
    //void setSettingsButtonEnabled(bool enable);

    //void updateButtonLayout();
    static QWizard::WizardStyle getStyle(const QString &name);

    //void setSilent(bool silent);
    //bool isSilent() const;

    //void setTextItems(QObject *object, const QStringList &items);

    // self define title bar, winter, 20180117
    /*void showHeadTitle(bool show, const QString& titleName = QString());
    QWidget* showProtocol(const QString& text = QString(), int x = 0, int y = 0, int width = 100, int height = 20);
    QWidget* showTipLabel(const QString& text = QString(), int x = 0, int y = 0, int width = 100, int height = 20);
    void setDragHeight(int iHeight);
    void setButtonText2(int wizardButton, const QString &name);*/
public:
	QString objTitle();
	QString objWindowTitle();
#ifndef Q_OS_OSX
	QString objWindowIcon();
#else
	QString objBackground();
#endif
	QWizard::WizardStyle objWizardStyle();
	QString objStyleSheet();

	int objCurrentId();
	//void objSetCurrentId(PackageManagerCore::WizardPage); // currentPageChanged()

	void addPage(int id, PackageManagerPageObj* page);
	void setPage(int index, int id, PackageManagerPageObj* page);
	void removePage(int id);
	QList<int> pageIds();
	int nextId();
	PackageManagerPageObj* page(int id);
	PackageManagerCore * core() { return m_core; }

	QObject* myPage(int id);
	virtual void nextPage();

Q_SIGNALS:
	void objReject();
	void objCancelAsk(QMessageBox::StandardButton &ask, bool &bInterrupt); // �������ͬ������

Q_SIGNALS:
    void interrupted();
    void languageChanged();
    void finishButtonClicked();
    void gotRestarted();
    //void settingsButtonClicked();
	

public Q_SLOTS:
    void cancelButtonClicked();
    void reject();
    void rejectWithoutPrompt();
    void showFinishedPage();
    //void setModified(bool value);

//protected Q_SLOTS:
Q_SIGNALS:
    void wizardPageInsertionRequested(QWidget *widget, QInstaller::PackageManagerCore::WizardPage page);
    void wizardPageRemovalRequested(QWidget *widget);
    void wizardWidgetInsertionRequested(QWidget *widget, QInstaller::PackageManagerCore::WizardPage page);
    void wizardWidgetRemovalRequested(QWidget *widget);
    void wizardPageVisibilityChangeRequested(bool visible, int page);
    void setValidatorForCustomPageRequested(QInstaller::Component *component, const QString &name,
                                            const QString &callbackName);

    //void setAutomatedPageSwitchEnabled(bool request); // 

private Q_SLOTS:
    //void onLanguageChanged();
    //void customButtonClicked(int which);
    void dependsOnLocalInstallerBinary();
    void currentPageChanged(int newId);

protected:
    //bool event(QEvent *event);
    void showEvent(QShowEvent *event); //����
    PackageManagerCore *packageManagerCore() const { return m_core; }
    void executeControlScript(int pageId);

private:
    class Private;
    Private *const d;
    PackageManagerCore *m_core;
};


// -- PackageManagerPage

class INSTALLER_EXPORT PackageManagerPageObj : public QObject
{
    Q_OBJECT

public:
    explicit PackageManagerPageObj(PackageManagerObj *obj);
    virtual ~PackageManagerPageObj() {}

    virtual QPixmap logoPixmap() const;
    virtual QString productName() const;
    virtual QPixmap watermarkPixmap() const;
    virtual QPixmap bannerPixmap(QWidget* widget) const;

    void setColoredTitle(const QString &title, QWizardPage* widget);
    void setColoredSubTitle(const QString &subTitle, QWizardPage* widget);

    virtual bool isComplete() const;
    void setComplete(bool complete);

    virtual bool isInterruptible() const { return false; }
    //PackageManagerObj* gui() const { return qobject_cast<PackageManagerGui*>(wizard()); }
	PackageManagerObj* gui() const { return m_gui; }

    void setValidatePageComponent(QInstaller::Component *component);

    bool validatePage();

    bool settingsButtonRequested() const { return m_needsSettingsButton; }
    void setSettingsButtonRequested(bool request) { m_needsSettingsButton = request; }

public:
	void objInitColor(QWidget* widget);
	void setErrorMessage(const QString &error);

signals:
	void completeChanged();

//public:
    //Q_INVOKABLE void setSpacing(int spacing);
    //Q_INVOKABLE void setContentsMargins(int left, int top, int right, int bottom);

signals:
    void entered();
    void left();

protected:
    PackageManagerCore *packageManagerCore() const;

    // Inserts widget into the same layout like a sibling identified
    // by its name. Default position is just behind the sibling.
    virtual void insertWidget(QWidget *widget, const QString &siblingName, int offset = 1);
    virtual QWidget *findWidget(const QString &objectName) const;

    virtual int nextId() const; // reimp

    // Used to support some kind of initializePage() in the case the wizard has been set
    // to QWizard::IndependentPages. If that option has been set, initializePage() would be only
    // called once. So we provide entering() and leaving() based on currentPageChanged() signal.
    virtual void entering() {} // called on entering
    virtual void leaving() {}  // called on leaving

private:
    bool m_complete;
    QString m_titleColor;
    bool m_needsSettingsButton;

	PackageManagerObj* m_gui;
    PackageManagerCore *m_core;
    QInstaller::Component *validatorComponent;

    friend class PackageManagerObj;
};


class INSTALLER_EXPORT IntroductionPageObj : public PackageManagerPageObj
{
	Q_OBJECT
public:
	explicit IntroductionPageObj(PackageManagerObj *obj);
	virtual ~IntroductionPageObj() {}

	bool validRepositoriesAvailable() const;

	void entering();

public Q_SLOTS:
	bool fetchUpdaterPackages();
	bool fetchCommonPackages();

private:
	bool m_updatesFetched;
	bool m_allPackagesFetched;
};

class INSTALLER_EXPORT PerformInstallationPageObj : public PackageManagerPageObj
{
	Q_OBJECT
public:
	explicit PerformInstallationPageObj(PackageManagerObj *obj);
	virtual ~PerformInstallationPageObj() {}

	void entering();

public Q_SLOTS:
	void updateProgress();
private:
	QTimer *m_updateTimer;
	int m_iLastProgress;
};

} //namespace QInstaller

#endif  // PACKAGEMANAGEROBJ_H
